home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / program / freeli20.zip / progs / squash.asm < prev    next >
Assembly Source File  |  1996-07-01  |  8KB  |  259 lines

  1. ; Simple executable-file compressor.
  2.  
  3. Ideal
  4. Jumps
  5.  
  6. Public      main
  7. Extrn       startup:near
  8.  
  9. Macro       lcall p,a,b,c,d,e,f,g,h ;; library call
  10.  
  11.             ifnb <a>
  12.               push a                ;; if args, push first arg
  13.               lcall p,b,c,d,e,f,g,h ;; and recurse . . .
  14.             else
  15.               extrn p:near          ;; declare procedure
  16.               call p                ;; call procedure
  17.             endif
  18.  
  19. EndM
  20.  
  21. Model Tiny
  22. Codeseg
  23. P186
  24. Org 100h
  25.  
  26. Start:      jmp startup
  27.  
  28. ;****************** Data Section
  29.  
  30. Syntax      db 'Syntax:  SQUASH <infile> <outfile>',0
  31.  
  32. ;****************** 'main' procedure
  33.  
  34. Proc        main
  35.  
  36.             lcall fsetbuf 16384     ;Set file buffers to 16K
  37.  
  38.             cmp cx,2                ;Wrong number of args?
  39.             jne m_syntax
  40.  
  41.             lcall fopen [di],0      ;Open input file
  42.             test ax,ax              ;File not found?
  43.             jz m_syntax
  44.             xchg bx,ax              ;BX = handle
  45.  
  46.             lcall fopen [di+2],3    ;Open output file
  47.             test ax,ax              ;Check for errors
  48.             jnz m_ok1
  49.             lcall fclose bx         ;Close input file
  50.             jmp m_syntax            ;Go print syntax
  51.  
  52. m_ok1:      xchg dx,ax              ;DX = handle
  53.  
  54.             push bx dx              ;Encode the file
  55.             call Encode
  56.  
  57.             lcall fclose bx         ;Close files
  58.             lcall fclose dx
  59.             ret                     ;Return
  60.  
  61. m_syntax:   push offset(Syntax)     ;Display 'Syntax' message
  62.             lcall puts
  63.             ret                     ;Return
  64.  
  65. EndP        main
  66.  
  67. ;The decoder prefix.  See the end of the file for the actual
  68. ;assembly lenguage code used to generate this block of data.
  69.  
  70. Decoder     dw 48736,354,4287,35707,6670,-3327,48804,284,191
  71.             dw 22510,185,-3327,50084
  72.  
  73. DLen        dw 0                    ;File length
  74.  
  75.             dw 191,45295,47392,4096,43763,4286,49019,256
  76.             dw 11915,282,37292,32949,49203,53811,-3446,53386
  77.             dw -9421,-374,-5167,-9678,-6272,33807,30157
  78.             dw 44037,34696,-4352,34698,-4352,53418,29645
  79.             dw 35331,17932,30029,25049,-6401
  80.  
  81. ;****************** Encode() -- Encode file
  82. ;void Encode(FILE *input, FILE *output)
  83.  
  84. input       equ bp+6
  85. output      equ bp+4
  86.  
  87. Proc        Encode
  88.  
  89.             push bp                 ;Set up stack frame
  90.             mov bp,sp
  91.             pusha                   ;Save all registers
  92.             push es
  93.  
  94.             lcall faralloc 256      ;Allocate 4K memory
  95.             test ax,ax              ;Out of memory?
  96.             jz p1_quit
  97.             mov es,ax               ;ES = memory
  98.  
  99.             xor di,di               ;Fill buffer with spaces:
  100.             mov al,20h              ;the most common character
  101.             mov cx,1000h
  102.             rep stosb
  103.  
  104.             lcall fseek [input],0,0,2 ;Get length
  105.             lcall ftell [input]
  106.             mov si,ax
  107.             mov [DLen],ax           ;Save length
  108.             lcall fseek [input],0,0,0
  109.  
  110.             push [output]           ;Write out decoder
  111.             push 98
  112.             push offset(Decoder)
  113.             lcall fwrite
  114.  
  115.             xor ax,ax               ;Zero AX, DX, DI
  116.             xor dx,dx
  117.             xor di,di
  118.             mov cx,8000h            ;CH = bit mask, CL = buffer
  119.  
  120. p1_loop:    mov dh,dl               ;Shift prev-chars
  121.             mov dl,al
  122.             lcall fgetc [input]     ;Load char
  123.  
  124.             xor bx,bx               ;Convert to 4K index
  125.             mov bh,dh
  126.             shr bx,1
  127.             xor bl,dl
  128.             and bh,0Fh
  129.  
  130.             cmp al,[es:bx]          ;Predicted it?
  131.             jne p1_char
  132.             or cl,ch                ;Set predict bit
  133.             jmp p1_cont
  134.  
  135. p1_char:    mov [es:bx],al          ;Set prediction
  136.             mov [p1_buf+di],al      ;Add char to buffer
  137.             inc di
  138.  
  139. p1_cont:    shr ch,1                ;Next bit
  140.             jnz p1_lb
  141.  
  142.             push ax                 ;Save AX
  143.  
  144.             lcall fputc [output],cx ;Output bit byte
  145.  
  146.             xor bx,bx               ;Zero BX
  147.             mov cx,di               ;No chars?
  148.             jcxz p1_cont2
  149.  
  150. p1_bloop:   push [output]           ;Output char
  151.             push [word p1_buf+bx]
  152.             lcall fputc
  153.             inc bx                  ;Next char
  154.             loop p1_bloop           ;Loop back
  155.  
  156. p1_cont2:   mov cx,8000h            ;Re-init bit buffer
  157.             xor di,di
  158.  
  159.             pop ax                  ;Restore AX
  160.  
  161. p1_lb:      dec si                  ;Loop back
  162.             jnz p1_loop
  163.  
  164.             cmp cx,8000h            ;Nothing, quit
  165.             je p1_done
  166.  
  167.             lcall fputc [output],cx ;Output final flags
  168.  
  169.             xor bx,bx               ;Zero BX
  170.             mov cx,di               ;No chars?
  171.             jcxz p1_done
  172.  
  173. p1_bloop2:  push [output]           ;Output char
  174.             push [word p1_buf+bx]
  175.             lcall fputc
  176.             inc bx                  ;Next char
  177.             loop p1_bloop2          ;Loop back
  178.  
  179. p1_done:    lcall farfree es        ;Free the memory
  180.  
  181. p1_quit:    pop es                  ;Restore registers
  182.             popa
  183.             pop bp                  ;Delete stack frame
  184.             ret 4                   ;Return
  185.  
  186. p1_buf      db 8 dup(0)
  187.  
  188. EndP        Encode
  189.  
  190. End Start
  191.  
  192. ; The executable decoder (98 bytes).  Decodes files up to
  193. ; 30K in length (after decoding).  Assumes SI = IP at start.
  194.  
  195. ; Start:      pusha                   ;Save all registers
  196. ;
  197. ;             mov si,offset Buffer    ;Relocate data buffer
  198. ;             mov di,31504
  199. ;             mov cx,[dlen]
  200. ;             rep movsb
  201. ;
  202. ;             mov si,offset Decode    ;Relocate decoder
  203. ;             mov di,0EE00h
  204. ;             push di
  205. ;             mov cx,256
  206. ;             rep movsb
  207. ;
  208. ;             ret                     ;Jump to decode code
  209. ;
  210. ; dlen        dw 0                    ;Length of file
  211. ;
  212. ; Decode:     mov di,0EF00h           ;Fill buffer with spaces:
  213. ;             mov al,20h              ;the most common character
  214. ;             mov cx,1000h
  215. ;             rep stosb
  216. ;
  217. ;             mov si,31504            ;SI = buffer, DI = start point
  218. ;             mov di,0100h
  219. ;
  220. ;             mov bp,[dlen]           ;BP = length
  221. ;
  222. ;             lodsb                   ;Init bit buffer
  223. ;             xchg cx,ax
  224. ;             mov ch,80h
  225. ;
  226. ;             xor ax,ax               ;Zero AX, DX
  227. ;             xor dx,dx
  228. ;
  229. ; DecLoop:    mov dh,dl               ;Shift prev-chars
  230. ;             mov dl,al
  231. ;
  232. ;             xor bx,bx               ;Convert to 4K index
  233. ;             mov bh,dh
  234. ;             shr bx,1
  235. ;             xor bl,dl
  236. ;             and bh,0Fh
  237. ;
  238. ;             test cl,ch              ;Check predict bit
  239. ;             jnz DecSkip
  240. ;
  241. ;             lodsb                   ;Wrong, set prediction
  242. ;             mov [bx+0EF00h],al
  243. ;
  244. ; DecSkip:    mov al,[bx+0EF00h]      ;Get prediction
  245. ;             stosb                   ;Output char
  246. ;
  247. ;             ror ch,1                ;Rotate mask
  248. ;             jnc $+5                 ;Check for wrap
  249. ;             mov cl,[si]             ;Load flag byte in CL
  250. ;             inc si
  251. ;
  252. ;             dec bp                  ;Loop back
  253. ;             jnz DecLoop
  254. ;
  255. ;             popa                    ;Restore registers
  256. ;             jmp si                  ;Jump to start
  257. ;
  258. ; Buffer:
  259.